package cn.iocoder.boot.springai001.config;

import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.spec.McpSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.mcp.customizer.McpSyncClientCustomizer;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.util.retry.Retry;

import java.time.Duration;
import java.util.List;

/**
 * MCP 客户端自定义配置器
 * 用于定制 MCP 客户端的行为，包括请求超时、事件处理等
 */
@Component
public class McpClientCustomizer implements McpSyncClientCustomizer {

    private static final Logger logger = LoggerFactory.getLogger(McpClientCustomizer.class);

    @Override
    public void customize(String serverConfigurationName, McpClient.SyncSpec spec) {
        logger.info("正在为服务器配置定制 MCP 客户端: {}", serverConfigurationName);

        // 1. 自定义请求超时配置
        spec.requestTimeout(Duration.ofSeconds(60));

        // 2. 添加工具变更监听器
        // 当 MCP 服务器的可用工具列表发生变化时（如工具被添加或移除），此监听器会收到通知
        spec.toolsChangeConsumer((List<McpSchema.Tool> tools) -> {
            logger.info("MCP 工具列表已更新，当前工具数量: {}", tools.size());
            tools.forEach(tool -> {
                logger.info("  - 工具名称: {}, 描述: {}", tool.name(), tool.description());
            });
        });

        // 3. 添加资源变更监听器
        // 当 MCP 服务器的可用资源列表发生变化时，此监听器会收到通知
        spec.resourcesChangeConsumer((List<McpSchema.Resource> resources) -> {
            logger.info("MCP 资源列表已更新，当前资源数量: {}", resources.size());
            resources.forEach(resource -> {
                logger.info("  - 资源 URI: {}, 名称: {}", resource.uri(), resource.name());
            });
        });

        // 4. 添加提示词变更监听器
        // 当 MCP 服务器的可用提示词列表发生变化时，此监听器会收到通知
        spec.promptsChangeConsumer((List<McpSchema.Prompt> prompts) -> {
            logger.info("MCP 提示词列表已更新，当前提示词数量: {}", prompts.size());
            prompts.forEach(prompt -> {
                logger.info("  - 提示词名称: {}, 描述: {}", prompt.name(), prompt.description());
            });
        });

        // 5. 添加日志消息监听器
        // 接收来自 MCP 服务器的结构化日志消息
        spec.loggingConsumer((McpSchema.LoggingMessageNotification log) -> {
            String level = log.level() != null ? log.level().toString() : "INFO";
            String data = log.data() != null ? log.data() : "";
            logger.info("MCP 服务器日志 [{}] {}: {}", serverConfigurationName, level, data);
        });

        logger.info("MCP 客户端定制完成: {}", serverConfigurationName);
    }
}

